#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

/**
标准输入输出流 （File *）
    FILE *stdin;   标准输入
    FILE *stdout;  标准输出
    FILE *stderr;  标准错误输出
标准输出输出流的文件描述符
    STDIN_FILENO    0  标准输入
    STDOUT_FILENO   1  标准输出
    STDERR_FILENO   2  标准错误输出
 */

int main(int argc, char const *argv[])
{
    //关闭标准输出和标准错误输出
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    //重定向标准输出和标准错误输出到文件log和err
    //文件描述符fd2=1，刚好对应STDOUT_FILENO   1  标准输出
    int fd1 = open("log.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644); 
    //文件描述符fd2=2(递归生成)，STDERR_FILENO   2  标准错误输出
    int fd2 = open("err.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);  

    //使用stdin控制台阻塞输入
    char input_buf[20];
    fgets(input_buf, sizeof(input_buf), stdin);
    //printf也会写进标准流
    printf("使用控制台输入input: %s\n", input_buf);
    //使用stdout控制台输出
    fputs("使用stdout输出到控制台(正常内容)\n",stdout);
    // 刷新缓冲区，将数据写入文件
    //主要作用是确保在调用它之前的所有输出都被立即发送到目标设备，而不是留在缓冲区中
    fflush(stdout); 
    //使用stderr控制台输出
    fputs("使用stderr输出到控制台(错误内容)\n",stderr);

    //使用文件描述符控制台输出
    // 使用STDIN_FILENO得到控制台输入
    char new_input_buf[20];
    read(STDIN_FILENO, new_input_buf, sizeof(new_input_buf));
    //printf也会写进标准流
    printf("使用文件描述符(STDIN_FILENO)得到控制台输入: %s\n", new_input_buf);
    // 使用STDOUT_FILENO得到控制台输出
    char *c1="使用文件描述符(STDOUT_FILENO)输出到控制台(正常内容)\n";
    write(STDOUT_FILENO, c1, strlen(c1)+1);     //结束符号+1
    // 使用STDERR_FILENO得到控制台输出
    char *c2="使用文件描述符(STDERR_FILENO)输出到控制台(错误内容)\n";
    write(STDERR_FILENO, c2, strlen(c2)+1);     //结束符号+1

    return 0;
}

